package com.unicom.office.func;

import com.unicom.office.runtime.OfficeRuntime;
import com.unicom.office.type.TypeItem;
import com.unicom.office.templatefunc.TemplateFunc;
import com.unicom.office.unit.OfficeUnit;

import java.util.ArrayList;
import java.util.List;

public class FuncNode extends FuncBase {
    private TemplateFunc templateFunc;
    protected List<Object> params;

    public FuncNode(TemplateFunc templateFunc){
        this.templateFunc = templateFunc;
        params = new ArrayList<Object>();
    }

    public Object run(OfficeRuntime officeRuntime){
        List<Object> list = handleParams(params, officeRuntime);
        return runBody(list, officeRuntime);
    }

    public void runForMatch(OfficeUnit unit, OfficeRuntime officeRuntime) {
        List<Object> list = handleParams(params, officeRuntime);
        templateFunc.runForMatch(unit, list, officeRuntime);
    }

    protected Object runBody(List<Object> params, OfficeRuntime officeRuntime) {
        return templateFunc.run(params, officeRuntime);
    }

    public TypeItem getType() {
        return templateFunc.getType();
    }

    public TemplateFunc getTemplateFunc() {
        return templateFunc;
    }

    public void setTemplateFunc(TemplateFunc templateFunc) {
        this.templateFunc = templateFunc;
    }

    protected List<Object> handleParams(List<Object> params, OfficeRuntime officeRuntime){
        List<Object> result = new ArrayList<Object>();
        for (Object param : params) {
            result.add(handleParam(param, officeRuntime));
        }
        return result;
    }

    private Object handleParam(Object param, OfficeRuntime officeRuntime){
        if (param instanceof FuncBase) {
            FuncBase funcNode = (FuncBase) param;
            Object result = funcNode.run(officeRuntime);
            return result;
        }else {
            return param;
        }
    }

    public List<Object> getParams() {
        return params;
    }

    public void addParam(Object param) {
        this.params.add(param);
    }

    public void addParams(List<Object> params){
        for (Object param : params) {
            addParam(param);
        }
    }
}
